#pragma once
#ifndef CLIB_QUEUE_H
#define CLIB_QUEUE_H

#include "clib_type.h"
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct clib_queue_s clib_queue_t;

struct clib_queue_s 
{
    clib_queue_t *prev;
    clib_queue_t *next;
};

#define clib_queue_init(queue)                       \
    (queue)->prev = queue;                           \
    (queue)->next = queue                     

#define clib_queue_empty(queue)                      \
    (queue == (queue)->prev)

#define clib_queue_insert_head(queue,node)           \
    (node)->next = (queue)->next;                    \
    (node)->next->prev = (node);                     \
    (node)->prev = (queue);                          \
    (queue)->next = (node)

#define clib_queue_insert_after   clib_queue_insert_head

#define clib_queue_insert_tail(queue, node)          \
    (node)->prev = (queue)->prev;                    \
    (node)->prev->next = (node);                     \
    (node)->next = (queue);                          \
    (queue)->prev = (node)

#define clib_queue_head(queue)                       \
    (queue)->next

#define clib_queue_tail(queue)                       \
    (queue)->prev

#define clib_queue_sentinel(queue)                   \
    (queue)   

#define clib_queue_next(queue)                       \
    (queue)->next

#define clib_queue_prev(queue)                       \
    (queue)->prev

#define clib_queue_remove(queue)                     \
    (queue)->next->prev = (queue)->prev;             \
    (queue)->prev->next = (queue)->next;             \
    (queue)->prev = queue;                           \
    (queue)->next = queue

#define clib_queue_merge_prev(queue, node)            \
    (queue)->prev->next = (node)->next;               \
    (node)->next->prev = (queue)->prev;               \
    (queue)->prev = (node)->prev;                     \
    (queue)->prev->next = (queue)

#define clib_queue_merge_next(queue, node)            \
    (queue)->next->prev = (node)->prev;               \
    (node)->prev->next = (queue)->next;               \
    (queue)->next = (node)->next;                     \
    (queue)->next->prev = (queue)

#define clib_queue_add  clib_queue_insert_tail

#define clib_queue_del  clib_queue_remove

#define clib_queue_data(ptr, type, link)             \
    (type *) ((i08_t *)(ptr) - offsetof(type, link))


#ifdef __cplusplus
}
#endif

#endif 

